home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / libs / kpathsea / variable.c < prev    next >
C/C++ Source or Header  |  1995-06-25  |  5KB  |  186 lines

  1. /* variable.c: variable expansion.
  2.  
  3. Copyright (C) 1993, 94 Karl Berry.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.  */
  18.  
  19. #include <kpathsea/config.h>
  20.  
  21. #include <kpathsea/c-ctype.h>
  22. #include <kpathsea/cnf.h>
  23. #include <kpathsea/fn.h>
  24. #include <kpathsea/variable.h>
  25.  
  26.  
  27. /* Append the result of value of `var' to EXPANSION, where `var' begins
  28.    at START and ends at END.  If `var' is not set, do not complain.  */
  29.  
  30. static void
  31. expand P3C(fn_type *, expansion,  const_string, start,  const_string, end)
  32. {
  33.   string value;
  34.   unsigned len = end - start + 1;
  35.   string var = xmalloc (len + 1);
  36.   strncpy (var, start, len);
  37.   var[len] = 0;
  38.   
  39.   /* First check the environment variable.  */
  40.   value = getenv (var);
  41.   
  42.   /* If no envvar, check the config files.  */
  43.   if (!value)
  44.     value = kpse_cnf_get (var);
  45.     
  46.   if (value)
  47.     {
  48.       value = kpse_var_expand (value);
  49.       fn_grow (expansion, value, strlen (value));
  50.       free (value);
  51.     }
  52.   
  53.   free (var);
  54. }
  55.  
  56. /* Can't think of when it would be useful to change these (and the
  57.    diagnostic messages assume them), but ... */
  58. #ifndef IS_VAR_START /* starts all variable references */
  59. #define IS_VAR_START(c) ((c) == '$')
  60. #endif
  61. #ifndef IS_VAR_CHAR  /* variable name constituent */
  62. #define IS_VAR_CHAR(c) (ISALNUM (c) || (c) == '_')
  63. #endif
  64. #ifndef IS_VAR_BEGIN_DELIMITER /* start delimited variable name (after $) */
  65. #define IS_VAR_BEGIN_DELIMITER(c) ((c) == '{')
  66. #endif
  67. #ifndef IS_VAR_END_DELIMITER
  68. #define IS_VAR_END_DELIMITER(c) ((c) == '}')
  69. #endif
  70.  
  71.  
  72. /* Maybe we should generalize to allow some or all of the various shell
  73.    ${...} constructs, especially ${var-value}.  */
  74.  
  75. string
  76. kpse_var_expand P1C(const_string, src)
  77. {
  78.   const_string s;
  79.   string ret;
  80.   fn_type expansion;
  81.   expansion = fn_init ();
  82.   
  83.   /* Copy everything but variable constructs.  */
  84.   for (s = src; *s; s++)
  85.     {
  86.       if (IS_VAR_START (*s))
  87.         {
  88.           s++;
  89.           
  90.           /* Three cases: `$VAR', `${VAR}', `$<anything-else>'.  */
  91.           
  92.           if (IS_VAR_CHAR (*s))
  93.             { /* $V: collect name constituents, then expand.  */
  94.               const_string var_end = s;
  95.               
  96.               do
  97.                 var_end++;
  98.               while (IS_VAR_CHAR (*var_end));
  99.               
  100.               var_end--; /* had to go one past */
  101.               expand (&expansion, s, var_end);
  102.               s = var_end;
  103.             }
  104.  
  105.           else if (IS_VAR_BEGIN_DELIMITER (*s))
  106.             { /* ${: scan ahead for matching delimiter, then expand.  */
  107.               const_string var_end = ++s;
  108.               
  109.               while (*var_end && !IS_VAR_END_DELIMITER (*var_end))
  110.                 var_end++;
  111.               
  112.               if (! *var_end)
  113.                 {
  114.                   WARNING1 ("%s: No matching right brace for ${", src);
  115.                   s = var_end - 1; /* will incr to null at top of loop */
  116.                 }
  117.               else
  118.                 {
  119.                   expand (&expansion, s, var_end - 1);
  120.                   s = var_end; /* will incr past } at top of loop*/
  121.                 }
  122.             }
  123.  
  124.  
  125.           else
  126.             { /* $<something-else>: error.  */
  127.               WARNING2 ("%s: Unrecognized variable construct `$%c'", src, *s);
  128.               /* Just ignore those chars and keep going.  */
  129.             }
  130.         }
  131.       else
  132.         fn_1grow (&expansion, *s);
  133.     }
  134.   fn_1grow (&expansion, 0);
  135.           
  136.   ret = FN_STRING (expansion);
  137.   return ret;
  138. }
  139.  
  140. #ifdef TEST
  141.  
  142. static void
  143. test_var (string test, string right_answer)
  144. {
  145.   string result = kpse_var_expand (test);
  146.   
  147.   printf ("expansion of `%s'\t=> %s", test, result);
  148.   if (!STREQ (result, right_answer))
  149.     printf (" [should be `%s']", right_answer);
  150.   putchar ('\n');
  151. }
  152.  
  153.  
  154. int
  155. main ()
  156. {
  157.    test_var ("a", "a");
  158.    test_var ("$foo", "");
  159.    test_var ("a$foo", "a");
  160.    test_var ("$foo a", " a");
  161.    test_var ("a$foo b", "a b");
  162.  
  163.    xputenv ("FOO", "foo value");
  164.    test_var ("a$FOO", "afoo value");
  165.    
  166.    xputenv ("Dollar", "$");
  167.    test_var ("$Dollar a", "$ a");
  168.    
  169.    test_var ("a${FOO}b", "afoo valueb");
  170.    test_var ("a${}b", "ab");
  171.    
  172.    test_var ("$$", ""); /* and error */
  173.    test_var ("a${oops", "a"); /* and error */
  174.    
  175.    return 0;
  176. }
  177.  
  178. #endif /* TEST */
  179.  
  180.  
  181. /*
  182. Local variables:
  183. standalone-compile-command: "gcc -g -I. -I.. -DTEST variable.c kpathsea.a"
  184. End:
  185. */
  186.